home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_061 / microemacs / eval.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  11KB  |  455 lines

  1. /*    EVAL.C:    Expresion evaluation functions for
  2.         MicroEMACS
  3.  
  4.     written 1986 by Daniel Lawrence                */
  5.  
  6. #include    <stdio.h>
  7. #include    "estruct.h"
  8. #include    "edef.h"
  9. #include    "evar.h"
  10.  
  11. #if    MEGAMAX & ST520
  12. overlay    "eval"
  13. #endif
  14.  
  15. char value[80];        /* buffer to return value in */
  16.  
  17. varinit()        /* initialize the user variable list */
  18.  
  19. {
  20.     register int i;
  21.  
  22.     for (i=0; i < MAXVARS; i++)
  23.         uv[i].u_name[0] = 0;
  24. }
  25.  
  26. char *gtfun(fname)    /* evaluate a function */
  27.  
  28. char *fname;        /* name of function to evaluate */
  29.  
  30. {
  31.     register int fnum;        /* index to function to eval */
  32.     register int status;        /* return status */
  33.     char arg1[NSTRING];        /* value of first argument */
  34.     char arg2[NSTRING];        /* value of second argument */
  35.     char arg3[NSTRING];        /* value of third argument */
  36.     static char result[2 * NSTRING];    /* string result */
  37.  
  38.     /* look the function up in the function table */
  39.     fname[3] = 0;    /* only first 3 chars significant */
  40.     for (fnum = 0; fnum < NFUNCS; fnum++)
  41.         if (strcmp(fname, funcs[fnum].f_name) == 0)
  42.             break;
  43.  
  44.     /* return errorm on a bad reference */
  45.     if (fnum == NFUNCS)
  46.         return(errorm);
  47.  
  48.     /* retrieve the first argument */
  49.     if ((status = macarg(arg1)) != TRUE)
  50.         return(errorm);
  51.  
  52.     /* if needed, retrieve the second argument */
  53.     if (funcs[fnum].f_type >= DYNAMIC) {
  54.         if ((status = macarg(arg2)) != TRUE)
  55.             return(errorm);
  56.  
  57.         /* if needed, retrieve the third argument */
  58.         if (funcs[fnum].f_type >= TRINAMIC)
  59.             if ((status = macarg(arg3)) != TRUE)
  60.                 return(errorm);
  61.     }
  62.  
  63.     /* and now evaluate it! */
  64.     switch (fnum) {
  65.         case UFADD:    return(itoa(atoi(arg1) + atoi(arg2)));
  66.         case UFSUB:    return(itoa(atoi(arg1) - atoi(arg2)));
  67.         case UFTIMES:    return(itoa(atoi(arg1) * atoi(arg2)));
  68.         case UFDIV:    return(itoa(atoi(arg1) / atoi(arg2)));
  69.         case UFMOD:    return(itoa(atoi(arg1) % atoi(arg2)));
  70.         case UFNEG:    return(itoa(-atoi(arg1)));
  71.         case UFCAT:    strcpy(result, arg1);
  72.                 return(strcat(result, arg2));
  73.         case UFLEFT:    return(strncpy(result, arg1, atoi(arg2)));
  74.         case UFRIGHT:    return(strcpy(result, &arg1[atoi(arg2)-1]));
  75.         case UFMID:    return(strncpy(result, &arg1[atoi(arg2)-1],
  76.                     atoi(arg3)));
  77.         case UFNOT:    return(ltos(stol(arg1) == FALSE));
  78.         case UFEQUAL:    return(ltos(atoi(arg1) == atoi(arg2)));
  79.         case UFLESS:    return(ltos(atoi(arg1) < atoi(arg2)));
  80.         case UFGREATER:    return(ltos(atoi(arg1) > atoi(arg2)));
  81.         case UFSEQUAL:    return(ltos(strcmp(arg1, arg2) == 0));
  82.         case UFSLESS:    return(ltos(strcmp(arg1, arg2) < 0));
  83.         case UFSGREAT:    return(ltos(strcmp(arg1, arg2) > 0));
  84.         case UFIND:    return(getval(arg1));
  85.     }
  86.  
  87.     exit(-11);    /* never should get here */
  88. }
  89.  
  90. char *gtusr(vname)    /* look up a user var's value */
  91.  
  92. char *vname;        /* name of user variable to fetch */
  93.  
  94. {
  95.  
  96.     register int vnum;    /* ordinal number of user var */
  97.  
  98.     /* scan the list looking for the user var name */
  99.     for (vnum = 0; vnum < MAXVARS; vnum++)
  100.         if (strcmp(vname, uv[vnum].u_name) == 0)
  101.             break;
  102.  
  103.     /* return errorm on a bad reference */
  104.     if (vnum == MAXVARS)
  105.         return(errorm);
  106.  
  107.     return(uv[vnum].u_value);
  108. }
  109.  
  110. char *gtenv(vname)
  111.  
  112. char *vname;        /* name of environment variable to retrieve */
  113.  
  114. {
  115.     register int vnum;    /* ordinal number of var refrenced */
  116.  
  117.     /* scan the list, looking for the referenced name */
  118.     for (vnum = 0; vnum < NEVARS; vnum++)
  119.         if (strcmp(vname, envars[vnum]) == 0)
  120.             break;
  121.  
  122.     /* return errorm on a bad reference */
  123.     if (vnum == NEVARS)
  124.         return(errorm);
  125.  
  126.     /* otherwise, fetch the appropriate value */
  127.     switch (vnum) {
  128.         case EVFILLCOL:    return(itoa(fillcol));
  129.         case EVPAGELEN:    return(itoa(term.t_nrow + 1));
  130.         case EVCURCOL:    return(itoa(getccol(FALSE)));
  131.         case EVCURLINE: return(itoa(getcline()));
  132.         case EVRAM:    return(itoa((int)(envram / 1024l)));
  133.         case EVFLICKER:    return(ltos(flickcode));
  134.         case EVCURWIDTH:return(itoa(term.t_nrow));
  135.         case EVCBUFNAME:return(curbp->b_bname);
  136.         case EVCFNAME:    return(curbp->b_fname);
  137.         case EVSRES:    return(sres);
  138.         case EVDEBUG:    return(ltos(macbug));
  139.         case EVSTATUS:    return(ltos(cmdstatus));
  140.     }
  141. }
  142.  
  143. int setvar(f, n)        /* set a variable */
  144.  
  145. int f;        /* default flag */
  146. int n;        /* numeric arg (can overide prompted value) */
  147.  
  148. {
  149.     register int vnum;    /* ordinal number of var refrenced */
  150.     register int status;    /* status return */
  151.     register int vtype;    /* type of variable to set */
  152.     register char * sp;    /* scratch string pointer */
  153.     char var[NVSIZE+1];    /* name of variable to fetch */
  154.     char value[NSTRING];    /* value to set variable to */
  155.  
  156.     /* first get the variable to set.. */
  157.     if (clexec == FALSE) {
  158.         status = mlreply("Variable to set: ", &var[0], NVSIZE);
  159.         if (status != TRUE)
  160.             return(status);
  161.     } else {    /* macro line argument */
  162.         /* grab token and skip it */
  163.         execstr = token(execstr, var);
  164.     }
  165.  
  166.     /* check the legality and find the var */
  167. sv01:    vtype = -1;
  168.     switch (var[0]) {
  169.  
  170.         case '$': /* check for legal enviromnent var */
  171.             for (vnum = 0; vnum < NEVARS; vnum++)
  172.                 if (strcmp(&var[1], envars[vnum]) == 0) {
  173.                     vtype = TKENV;
  174.                     break;
  175.                 }
  176.             break;
  177.  
  178.         case '%': /* check for existing legal user variable */
  179.             for (vnum = 0; vnum < MAXVARS; vnum++)
  180.                 if (strcmp(&var[1], uv[vnum].u_name) == 0) {
  181.                     vtype = TKVAR;
  182.                     break;
  183.                 }
  184.             if (vnum < MAXVARS)
  185.                 break;
  186.  
  187.             /* create a new one??? */
  188.             for (vnum = 0; vnum < MAXVARS; vnum++)
  189.                 if (uv[vnum].u_name[0] == 0) {
  190.                     vtype = TKVAR;
  191.                     strcpy(uv[vnum].u_name, &var[1]);
  192.                     break;
  193.                 }
  194.             break;
  195.  
  196.         case '&':    /* indirect operator? */
  197.             var[4] = 0;
  198.             if (strcmp(&var[1], "ind") == 0) {
  199.                 /* grab token, and eval it */
  200.                 execstr = token(execstr, var);
  201.                 strcpy(var, getval(var));
  202.                 goto sv01;
  203.             }
  204.     }
  205.  
  206.     /* if its not legal....bitch */
  207.     if (vtype == -1) {
  208.         mlwrite("%%No such variable");
  209.         return(FALSE);
  210.     }
  211.  
  212.     /* get the value for that variable */
  213.     if (f == TRUE)
  214.         strcpy(value, itoa(n));
  215.     else {
  216.         status = mlreply("Value: ", &value[0], NSTRING);
  217.         if (status != TRUE)
  218.             return(status);
  219.     }
  220.  
  221.     /* and set the appropriate value */
  222.     status = TRUE;
  223.     switch (vtype) {
  224.     case TKVAR: /* set a user variable */
  225.         if (uv[vnum].u_value != NULL)
  226.             free(uv[vnum].u_value);
  227.         sp = malloc(strlen(value) + 1);
  228.         if (sp == NULL)
  229.             return(FALSE);
  230.         strcpy(sp, value);
  231.         uv[vnum].u_value = sp;
  232.         break;
  233.  
  234.     case TKENV: /* set an environment variable */
  235.         status = TRUE;    /* by default */
  236.         switch (vnum) {
  237.         case EVFILLCOL:    fillcol = atoi(value);
  238.                 break;
  239.         case EVPAGELEN:    status = newsize(TRUE, atoi(value));
  240.                 break;
  241.         case EVCURCOL:    status = setccol(atoi(value));
  242.                 break;
  243.         case EVCURLINE:    status = gotoline(TRUE, atoi(value));
  244.                 break;
  245.         case EVRAM:    break;
  246.         case EVFLICKER:    flickcode = stol(value);
  247.                 break;
  248.         case EVCURWIDTH:status = newwidth(TRUE, atoi(value));
  249.                 break;
  250.         case EVCBUFNAME:strcpy(curbp->b_bname, value);
  251.                 curwp->w_flag |= WFMODE;
  252.                 break;
  253.         case EVCFNAME:    strcpy(curbp->b_fname, value);
  254.                 curwp->w_flag |= WFMODE;
  255.                 break;
  256.         case EVSRES:    status = TTrez(value);
  257.                 break;
  258.         case EVDEBUG:    macbug = stol(value);
  259.                 break;
  260.         case EVSTATUS:    cmdstatus = stol(value);
  261.                 break;
  262.         }
  263.         break;
  264.     }
  265.     return(status);
  266. }
  267.  
  268. /*    atoi:    ascii string to integer......This is too
  269.         inconsistant to use the system's    */
  270.  
  271. atoi(st)
  272.  
  273. char *st;
  274.  
  275. {
  276.     int result;    /* resulting number */
  277.     int sign;    /* sign of resulting number */
  278.     char c;        /* current char being examined */
  279.  
  280.     result = 0;
  281.     sign = 1;
  282.     while ((c = *st++)) {
  283.         if (c == '-')
  284.             sign *= -1;
  285.         if (c >= '0' && c <= '9')
  286.             result = result * 10 + c - '0';
  287.     }
  288.  
  289.     return(result * sign);
  290. }
  291.  
  292. /*    itoa:    integer to ascii string.......... This is too
  293.         inconsistant to use the system's    */
  294.  
  295. char *itoa(i)
  296.  
  297. int i;    /* integer to translate to a string */
  298.  
  299. {
  300.     register int digit;        /* current digit being used */
  301.     register char *sp;        /* pointer into result */
  302.     register int sign;        /* sign of resulting number */
  303.     static char result[INTWIDTH+1];    /* resulting string */
  304.  
  305.     /* eliminate the trivial 0 */
  306.     if (i == 0)
  307.         return("0");
  308.  
  309.     /* record the sign...*/
  310.     sign = 1;
  311.     if (i < 0) {
  312.         sign = -1;
  313.         i = -i;
  314.     }
  315.  
  316.     /* and build the string (backwards!) */
  317.     sp = result + INTWIDTH;
  318.     *sp = 0;
  319.     while (i) {
  320.         digit = i % 10;
  321.         *(--sp) = '0' + digit;    /* and install the new digit */
  322.         i = i / 10;
  323.     }
  324.  
  325.     /* and fix the sign */
  326.     if (sign == -1) {
  327.         *(--sp) = '-';    /* and install the minus sign */
  328.     }
  329.  
  330.     return(sp);
  331. }
  332.  
  333. int gettyp(token)    /* find the type of a passed token */
  334.  
  335. char *token;    /* token to analyze */
  336.  
  337. {
  338.     register char c;    /* first char in token */
  339.  
  340.     /* grab the first char (this is all we need) */
  341.     c = *token;
  342.  
  343.     /* no blanks!!! */
  344.     if (c == 0)
  345.         return(TKNUL);
  346.  
  347.     /* a numeric literal? */
  348.     if (c >= '0' && c <= '9')
  349.         return(TKLIT);
  350.  
  351.     switch (c) {
  352.         case '"':    return(TKSTR);
  353.  
  354.         case '!':    return(TKDIR);
  355.         case '@':    return(TKARG);
  356.         case '#':    return(TKBUF);
  357.         case '$':    return(TKENV);
  358.         case '%':    return(TKVAR);
  359.         case '&':    return(TKFUN);
  360.         case '*':    return(TKLBL);
  361.  
  362.         default:    return(TKCMD);
  363.     }
  364. }
  365.  
  366. char *getval(token)    /* find the value of a token */
  367.  
  368. char *token;        /* token to evaluate */
  369.  
  370. {
  371.     register int status;    /* error return */
  372.     register BUFFER *bp;    /* temp buffer pointer */
  373.     register int blen;    /* length of buffer argument */
  374.     char buf[NSTRING];    /* string buffer for some returns */
  375.  
  376.     switch (gettyp(token)) {
  377.         case TKNUL:    return("");
  378.  
  379.         case TKARG:    /* interactive argument */
  380.                 status = getstring(getval(&token[1]),
  381.                        buf, NSTRING, ctoec('\n'));
  382.                 if (status == ABORT)
  383.                     return(errorm);
  384.                 return(buf);
  385.  
  386.         case TKBUF:    /* buffer contents fetch */
  387.  
  388.                 /* grab the right buffer */
  389.                 bp = bfind(getval(&token[1]), FALSE, 0);
  390.                 if (bp == NULL)
  391.                     return(errorm);
  392.         
  393.                 /* make sure we are not at the end */
  394.                 if (bp->b_linep == bp->b_dotp)
  395.                     return(errorm);
  396.         
  397.                 /* grab the line as an argument */
  398.                 blen = bp->b_dotp->l_used;
  399.                 if (blen > NSTRING)
  400.                     blen = NSTRING;
  401.                 strncpy(buf, bp->b_dotp->l_text, blen);
  402.                 buf[blen] = 0;
  403.         
  404.                 /* and step the buffer's line ptr ahead a line */
  405.                 bp->b_dotp = bp->b_dotp->l_fp;
  406.                 bp->b_doto = 0;
  407.  
  408.                 /* and return the spoils */
  409.                 return(buf);        
  410.  
  411.         case TKVAR:    return(gtusr(token+1));
  412.         case TKENV:    return(gtenv(token+1));
  413.         case TKFUN:    return(gtfun(token+1));
  414.         case TKDIR:    return(errorm);
  415.         case TKLBL:    return(itoa(gtlbl(token)));
  416.         case TKLIT:    return(token);
  417.         case TKSTR:    return(token+1);
  418.         case TKCMD:    return(token);
  419.     }
  420. }
  421.  
  422. gtlbl(token)    /* find the line number of the given label */
  423.  
  424. char *token;    /* label name to find */
  425.  
  426. {
  427.     return(1);
  428. }
  429.  
  430. int stol(val)    /* convert a string to a numeric logical */
  431.  
  432. char *val;    /* value to check for stol */
  433.  
  434. {
  435.     /* check for logical values */
  436.     if (val[0] == 'F')
  437.         return(FALSE);
  438.     if (val[0] == 'T')
  439.         return(TRUE);
  440.  
  441.     /* check for numeric truth (!= 0) */
  442.     return((atoi(val) != 0));
  443. }
  444.  
  445. char *ltos(val)        /* numeric logical to string logical */
  446.  
  447. int val;    /* value to translate */
  448.  
  449. {
  450.     if (val)
  451.         return(truem);
  452.     else
  453.         return(falsem);
  454. }
  455.